package net.sf.jml.message.p2p;

import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import net.sf.jml.MsnObject;

public class DisplayPictureDuelManager {

	protected static DisplayPictureDuelManager dm = new DisplayPictureDuelManager();

	public static synchronized DisplayPictureDuelManager getDuelManager() {
		return dm;
	}

	private static final ScheduledExecutorService THREAD_EXECUTOR = Executors.newScheduledThreadPool(1); 
	private List<DisplayPictureDuel> duels;

	private Hashtable<String, RemovableMsnObject> pictures;
	private MsnObject displayPicture;

	private DisplayPictureDuelManager() {
		duels = new ArrayList<DisplayPictureDuel>();
		pictures = new Hashtable<String, RemovableMsnObject>();
		THREAD_EXECUTOR.scheduleWithFixedDelay(new RemoveMsnObjectWorker(), 10*60,
			10*60, TimeUnit.SECONDS);
	}

	public synchronized void add(DisplayPictureDuel duel) {
		duels.add(duel);
	}

	public synchronized DisplayPictureDuel get(int baseId) {
		for(DisplayPictureDuel item : duels) {
			if (item.getBaseId() == baseId) {
				return item;
			}
		}
		return null;
	}

	public synchronized boolean remove(int baseId) {
		DisplayPictureDuel duel = get(baseId);
		return duels.remove(duel);
	}

	public int getSize() {
		return duels.size();
	}

	public void putPicture(String key, MsnObject obj) {
		RemovableMsnObject msnObj = new RemovableMsnObject(obj);
		pictures.put(key, msnObj);
	}

	public MsnObject getPicture(String key) {
		RemovableMsnObject ret = pictures.get(key);
		if (ret != null) {
			return ret.getMsnObject();
		}
		return getDisplayPicutre();
	}

	public MsnObject getDisplayPicutre() {
		return displayPicture;
	}

	public void setDisplayPicutre(MsnObject displayPicutre) {
		this.displayPicture = displayPicutre;
	}

	class RemovableMsnObject {

		private MsnObject msnObject;

		private long lastAccessedTime;

		public RemovableMsnObject(MsnObject msnObject) {
			this.msnObject = msnObject;
			this.lastAccessedTime = Calendar.getInstance().getTimeInMillis();
		}

		public long getLastAccessedTime() {
			return lastAccessedTime;
		}

		public MsnObject getMsnObject() {
			this.lastAccessedTime = Calendar.getInstance().getTimeInMillis();
			return msnObject;
		}
	}
	
	private class RemoveMsnObjectWorker implements Runnable {
		/*
		 * (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		public void run() {
            try {
                long now = Calendar.getInstance().getTimeInMillis();
                Iterator<Map.Entry<String, RemovableMsnObject>> iter = pictures.entrySet().iterator();
                while (iter.hasNext()) {
                	Map.Entry<String, RemovableMsnObject> entry = iter.next();
        			RemovableMsnObject pic = entry.getValue();
        			if (pic != null && (now - pic.getLastAccessedTime() > 1000*60*20)){
        				iter.remove();
          			}
        		}
            } catch (RuntimeException e) {
            	e.printStackTrace();
            }
        }
    }
	
}
